using System;
using System.Collections.Generic;
using Clandestine.Engines.Field;

namespace Shlick.LayerModel
{
	internal class LayerGroupItem : Item
	{
		public LayerGroup LayerGroup { get; private set; }
		
		private LayerGroupItem(LayerGroup item, MapDocument mapDocument, LayerTreeMode mode) : base(item, mapDocument, mode)
		{
			this.LayerGroup = item;
		}
		
		public static LayerGroupItem Get(LayerGroup item, MapDocument mapDocument, LayerTreeMode mode)
		{
			if (cachedItems.ContainsKey(mode) && cachedItems[mode].ContainsKey(item))
				return (LayerGroupItem)cachedItems[mode][item];
			else
				return new LayerGroupItem(item, mapDocument, mode);
		} 
		
		public override void ContextMenuRequested (LayerTreeView parent, Qyoto.QPoint pos)
		{
			IContextMenu menu = new LayerGroupMenu(parent, this.MapDocument, this.LayerGroup);
			menu.Show();
		}
		
		public override int Row()
		{
			// Depends on what the parent is!
			if (this.LayerGroup.Parent is Level)
			{
				Level l = (Level)this.LayerGroup.Parent;
				if (l.SkyLayers == this.LayerGroup)
					return 0;
				else if (l.FloorLayers == this.LayerGroup)
					return 1;
			}
			else if (this.LayerGroup.Parent is Clandestine.Engines.Field.Object)
			{
				Clandestine.Engines.Field.Object o = (Clandestine.Engines.Field.Object)this.LayerGroup.Parent;
				if (o.SkyLayers == this.LayerGroup)
					return 0;
				else if (o.PerpendicularLayers == this.LayerGroup)
					return 1;
				else if (o.FloorLayers == this.LayerGroup)
					return 2;
			}
			throw new Exception();
		}
		
		public override Item Child(int row)
		{
			if (this.Mode == LayerTreeMode.Level)
				return null;
				
			if (row >= this.LayerGroup.Layers.Count)
				return null;
				
			// reverse order so that layers with bigger depths have smaller row number!
			return LayerItem.Get(this.LayerGroup.Layers[this.LayerGroup.Layers.Count - row - 1], this.MapDocument, this.Mode);
		}
		
		public override Item Parent()
		{
			// Could be a LevelItem or a ObjectItem
			if (this.LayerGroup.Parent is Level)
				return LevelItem.Get((Level)this.LayerGroup.Parent, this.MapDocument, this.Mode);
			else if (this.LayerGroup.Parent is Clandestine.Engines.Field.Object)
				return ObjectItem.Get((Clandestine.Engines.Field.Object)this.LayerGroup.Parent, this.MapDocument, this.Mode);
			throw new Exception();
		}
		
		public override int ChildrenCount()
		{
			if (this.Mode == LayerTreeMode.Level)
				return 0;
			else
				return this.LayerGroup.Layers.Count;
		}
		
		public override string GetData()
		{
			// Depends on what the parent is!
			if (this.LayerGroup.Parent is Level)
			{
				Level l = (Level)this.LayerGroup.Parent;
				if (l.SkyLayers == this.LayerGroup)
					return "Sky Layers";
				else if (l.FloorLayers == this.LayerGroup)
					return "Floor Layers";
			}
			
			else if (this.LayerGroup.Parent is Clandestine.Engines.Field.Object)
			{
				Clandestine.Engines.Field.Object o = (Clandestine.Engines.Field.Object)this.LayerGroup.Parent;
				if (o.SkyLayers == this.LayerGroup)
					return "Sky Layers";
				else if (o.PerpendicularLayers == this.LayerGroup)
					return "Perpendicular Layers";
				else if (o.FloorLayers == this.LayerGroup)
					return "Floor Layers";
			}
			throw new Exception();
		}
		
		public override string GetName()
		{
			return string.Empty;
		}
		
		public override bool? IsVisible()
		{
			 return this.LayerGroup.Visible;
		}
		
		public override bool SetVisible(bool visible)
		{
			this.LayerGroup.Visible = visible;
			return true;
		}
		
		public override uint Flags ()
		{
			return base.Flags() | (uint)(ItemFlag.ItemIsDropEnabled);
		}
	}
}